package com.zwj.batch.config.test;

import com.zwj.batch.validators.NameParamValidator;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.job.CompositeJobParametersValidator;
import org.springframework.batch.core.job.DefaultJobParametersValidator;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Map;

/**
 * 参数校验: 自定义参数校验器、默认参数校验器、组合参数校验器
 * @author 张文接
 * @version 1.0
 * @createTime 2023-05-21 16:21:00
 */
//@Configuration
public class BatchConfig03 {
    //job构造工厂
    @Resource
    private JobBuilderFactory jobBuilderFactory;
    //step构造工厂
    @Resource
    private StepBuilderFactory stepBuilderFactory;

    /**
     * 逻辑主体
     *
     * @return
     */
    @StepScope
    @Bean
    public Tasklet tasklet() {
        return new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
                Map<String, Object> jobParameters = chunkContext.getStepContext().getJobParameters();
                System.out.println("参数：name = " + jobParameters.get("name"));
                System.out.println("参数：age = " + jobParameters.get("age"));
                return RepeatStatus.FINISHED;
            }
        };
    }

    @Bean
    public Job job() {
        return jobBuilderFactory.get("job07-composite-param-validate")//给job命名
                .start(step1())//具体执行什么步骤(step)
                .validator(compositeJobParametersValidator()).build();
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("compositeParamValidateStep")//给step命名
                .tasklet(tasklet())//注入具体要执行的逻辑
                .build();//构建
    }

    @Bean
    public NameParamValidator validator() {
        return new NameParamValidator();
    }

    /**
     * 默认参数校验器
     * 可以设置那些字段是必须有的
     *
     * @return
     */
    @Bean
    public DefaultJobParametersValidator defaultJobParametersValidator() {
        DefaultJobParametersValidator defaultJobParametersValidator = new DefaultJobParametersValidator();
        //设置必传的参数
        defaultJobParametersValidator.setRequiredKeys(new String[]{"name"});
        //设置选填的参数
        defaultJobParametersValidator.setOptionalKeys(new String[]{"age"});
        return defaultJobParametersValidator;
    }

    /**
     * 组合校验器案例
     * 需求：要求步骤中必须有name属性，并且不能为空
     *
     * @return
     */
    @Bean
    public CompositeJobParametersValidator compositeJobParametersValidator() {
        //默认校验器，必须有name属性
        DefaultJobParametersValidator validator = new DefaultJobParametersValidator();
        validator.setRequiredKeys(new String[]{"name"});
        validator.setOptionalKeys(new String[]{"age"});

        //name不能为空
        NameParamValidator nameParamValidator = validator();

        //组合校验器--将上述2个校验器组合到一起
        CompositeJobParametersValidator compositeValidator = new CompositeJobParametersValidator();
        compositeValidator.setValidators(Arrays.asList(validator, nameParamValidator));

        //判断校验器是否为空
        try {
            compositeValidator.afterPropertiesSet();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return compositeValidator;
    }
}
